﻿using System;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Input;

namespace Wheels.Windows
{
    public static class User32
    {
#pragma warning disable 1591

        #region Constants

        public static readonly IntPtr HWndBroadcast = new IntPtr(0xffff);
        public static readonly IntPtr HWndTop = new IntPtr(0);
        public static readonly IntPtr HWndBottom = new IntPtr(1);
        public static readonly IntPtr HWndTopmost = new IntPtr(-1);
        public static readonly IntPtr HWndNoTopmost = new IntPtr(-2);
        public static readonly IntPtr HWndMessage = new IntPtr(-3);

        #endregion

        #region Flags

        public enum WM : int
        {
            HotKey = 0x312
        }

        [Flags]
        public enum SetWindowPosFlags : int
        {
            None = 0,
            NoSize = 0x0001,
            NoMove = 0x0002,
            NoZOrder = 0x0004,
            NoRedraw = 0x0008,
            NoActivate = 0x0010,
            DrawFrame = 0x0020,
            FrameChanged = 0x0020,
            ShowWindow = 0x0040,
            HideWindow = 0x0080,
            NoCopyBits = 0x0100,
            NoOwnerZOrder = 0x0200,
            NoReposition = 0x0200,
            NoSendChangingEvent = 0x0400,
            DeferErase = 0x2000,
            AsynchronousWindowPosition = 0x4000,
        }

        public enum WindowLongIndex : int
        {
            ExStyle = -20,
            HInstance = -6,
            HWindowParent = -8,
            ID = -12,
            Style = -16,
            UserData = -21,
            WindowProc = -4,
            DialogUser = 0x8,
            DialogMessageResult = 0x0,
            DialogProc = 0x4
        }

        [Flags]
        public enum WindowStylesEx
        {
            AcceptFiles = 0x00000010,
            AppWindow = 0x00040000,
            ClientEdge = 0x00000200,
            Composited = 0x02000000,
            ContextHelp = 0x00000400,
            ControlParent = 0x00010000,
            DialogModalFrame = 0x00000001,
            Layered = 0x00080000,
            LayoutRtl= 0x00400000,
            Left = 0x00000000,
            LeftScrollbar = 0x00004000,
            LtrReading = 0x00000000,
            MdiChild = 0x00000040,
            NoActivate = 0x08000000,
            NoInheritLayout = 0x00100000,
            NoParentNotify = 0x00000004,
            Right = 0x00001000,
            RightScrollbar = 0x00000000,
            RtlReading = 0x00002000,
            StaticEdge = 0x00020000,
            ToolWindow = 0x00000080,
            Topmost = 0x00000008,
            Transparent = 0x00000020,
            WindowEdge = 0x00000100,

            OverlappedWindow = WindowEdge | ClientEdge,
            PaletteWindow = WindowEdge | ToolWindow | Topmost,
        }

        #endregion

        #region Procedures

        public delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam);

        #endregion

        #region Functions

        public const string DllName = "User32.DLL";

        [DllImport(DllName)]
        public static extern IntPtr LoadIcon(IntPtr hModule, IntPtr id);
        [DllImport(DllName, CharSet = CharSet.Unicode)]
        public static extern IntPtr LoadIcon(IntPtr hModule, string name);
        [DllImport(DllName)]
        public static extern bool DestroyIcon(IntPtr hIcon);

        [DllImport(DllName, SetLastError = true)]
        public static extern bool RegisterHotKey(IntPtr handle, int id, int modifiers, int vk);

        public static bool RegisterHotKey(IntPtr handle, int id, ModifierKeys modifiers, Key key)
        {
            return RegisterHotKey(handle, id, (int)modifiers, KeyInterop.VirtualKeyFromKey(key));
        }

        [DllImport(DllName, SetLastError = true)]
        public static extern bool UnregisterHotKey(IntPtr handle, int id);

        [DllImport(DllName)]
        public static extern IntPtr GetForegroundWindow();

        [DllImport(DllName)]
        public static extern bool SetForegroundWindow(IntPtr hWnd);

        [DllImport(DllName, SetLastError = true, CharSet = CharSet.Unicode)]
        public static extern int GetWindowTextLength(IntPtr hWnd);

        [DllImport(DllName, SetLastError = true, CharSet = CharSet.Unicode)]
        public static extern int GetWindowText(IntPtr hWnd, StringBuilder buffer, int size);

        [DllImport(DllName, SetLastError = true)]
        public static extern int GetWindowLong(IntPtr hWnd, WindowLongIndex index);

        [DllImport(DllName, SetLastError = true, CharSet = CharSet.Unicode)]
        public static extern IntPtr GetWindowLongPtr(IntPtr hWnd, WindowLongIndex index);

        [DllImport(DllName, SetLastError = true)]
        public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, SetWindowPosFlags flags);

        [DllImport(DllName, SetLastError = true)]
        public static extern IntPtr SetClipboardViewer(IntPtr hWndNewViewer);

        [DllImport(DllName)]
        public static extern bool ChangeClipboardChain(IntPtr hWndRemove, IntPtr hWndNewNext);

        [DllImport(DllName, SetLastError = true, CharSet = CharSet.Unicode)]
        public static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);

        #endregion
    }
}
